package com.lysj.admin.gateway.filter;

import cn.hutool.core.util.ReUtil;
import com.lysj.admin.gateway.GateApplicationRunner;
import com.lysj.admin.gateway.config.AuthenticationIssuers;
import com.lysj.admin.gateway.config.IgnoredUrls;
import com.lysj.admin.gateway.constants.GatewayConstants;
import com.lysj.admin.gateway.constants.JwtUtils;
import com.lysj.admin.utils.annotation.SystemLog;
import com.lysj.admin.utils.json.JacksonUtil;
import com.lysj.admin.utils.web.ParamUtil;
import com.lysj.admin.utils.web.Resp;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * @author Created by zk on 2019-01-16 15:57
 * @description
 */
@Slf4j
public class PreFilter extends ZuulFilter {
    @Resource
    private AuthenticationIssuers authenticationIssuers;
    @Value("${secret.header}")
    private String header;
    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 3;
    }

    /*
     * @author Created by zk on 2019/1/3 15:46
     * @Description 动态判断该路径是否需要鉴权
     */
    @Override
    public boolean shouldFilter() {
        //获取需要忽略的权限列表进行匹配
        HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
        String path = request.getRequestURI();
        //此处遍历忽略列表集，若匹配则不启动该过滤器
        boolean isSuccess = true;//是否成功，用于传达上一个过滤器的状态，若为false，则下一个过滤器不会执行
        for (String s : GateApplicationRunner.authIgnoreReg) {
            if(ReUtil.isMatch(s,path)){
                isSuccess = false;
                break;
            }
        }
        // TODO: 2019/1/16 此处应添加访问日志信息
        log.info("This is PreFilter,path:"+path);
        request.setAttribute(GatewayConstants.IS_SUCCESS_NAME,isSuccess);
        //若该路径不在忽略列表中，则必带token
        if(isSuccess){
            return true;
        }
        return false;
    }

    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String token = request.getHeader(header);
        if(ParamUtil.isBlank(token)){
            request.setAttribute(GatewayConstants.IS_SUCCESS_NAME,false);
            ctx.setSendZuulResponse(false);
            ctx.setResponseBody(JacksonUtil.toJson(new Resp().error(Resp.Status.NO_LOGIN,"您尚未登录")));
            ctx.getResponse().setContentType("application/json; charset=utf-8");
            return null;
        }
        String iss = JwtUtils.tokenIssValue(token);
        if(ParamUtil.isBlank(iss) || checkIss(iss)){
            request.setAttribute(GatewayConstants.IS_SUCCESS_NAME,false);
            ctx.setSendZuulResponse(false);
            ctx.setResponseBody(JacksonUtil.toJson(new Resp().error(Resp.Status.TOKEN_ERROR,"token有误,请重新登录")));
            ctx.getResponse().setContentType("application/json; charset=utf-8");
            return null;
        }
        request.setAttribute(GatewayConstants.JWT_ISSUER,iss);
        return null;
    }

    //判断Iss是否合法
    private boolean checkIss(String iss){
        for (String s : authenticationIssuers.getNames()) {
            if(s.equals(iss)){
                return false;
            }
        }
        return true;
    }


}
